package com.atguigu.day03;

/**
 * @ClassName CASDemo
 * @Description 此类描述:开100个线程各自增100次,并去最终值
 * @Author dangchen
 * @DateTime 2022-09-08 18:51
 * @Version 1.0
 */

import com.sun.javafx.robot.FXRobotImage;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * CAS : (Compare and Swap)比较并交换的一种技术 三值比较:内存值 预期值 更新值  弊端:自旋
 * Before: 多线程环境  不使用CAS 就要加锁保证数据安全(基本数据类型) 影响性能
 * After:  多线程环境  在原子类AtomicInterger可以用CAS技术来保证数据安全(基本数据类型)  不用加锁
 */
public class CASDemo {
    //不用CAS技术
   private volatile int number = 0;//volatile通知可以取值了

    public int getNumber() {
        return number;
    }

    public synchronized void setNumber() {
        this.number++;
    }

    //在AtomicInteger中用CAS
    private AtomicInteger atomicInteger = new AtomicInteger(0);

    public AtomicInteger getAtomicInteger() {
        return atomicInteger;
    }

    public void setAtomicInteger() {
        this.atomicInteger.incrementAndGet();
    }

    public static void main(String[] args) throws InterruptedException {
        CASDemo casDemo = new CASDemo();
        CountDownLatch countDownLatch = new CountDownLatch(100);
        for (int i = 0; i < 100 ; i++) {
            new Thread(() -> {
                for (int j = 0; j < 100; j++) {
                    casDemo.setAtomicInteger();
                }
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
        countDownLatch.await();//要拦下main方法,CAS技术只确保取值的时候线程安全,不用加锁
        System.out.println("最终结果是: \t" + casDemo.getAtomicInteger().get());
    }

    private static void NoCAS() throws InterruptedException {
        CASDemo casDemo = new CASDemo();
        CountDownLatch countDownLatch = new CountDownLatch(100);
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                for (int j = 0; j <100 ; j++) {
                    casDemo.setNumber();
                }
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }

        /*try { //工作中不用sleep,用CountDownLatch
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
        countDownLatch.await();
        System.out.println("最终结果 \t" + casDemo.getNumber());
    }


    //AtomicInteger类中CAS技术应用demo
    private static void HelloCas() {
        AtomicInteger atomicInteger = new AtomicInteger(5);
        System.out.println(atomicInteger.compareAndSet(5,25) + "\t" + atomicInteger.get());
        System.out.println(atomicInteger.compareAndSet(5,30) + "\t" + atomicInteger.get());
    }
}
